package kandl.automation.junit.exception;

import com.google.common.base.Joiner;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;

import kandl.automation.testsuite.TestCase;
import kandl.automation.testsuite.TestProfile;
import kandl.automation.testsuite.TestStep;
import kandl.automation.testsuite.TestSuite;
import static com.google.common.collect.Lists.newArrayList;

public class FailedTestCaseException extends Throwable {

    private final TestCase testCase;
    private final TestProfile profile;
    private final TestSuite suite;
    
    private LinkedHashMap<TestStep, Exception> failedSteps;
    private Map<TestStep, String> screenshots;

    public FailedTestCaseException(TestCase testCase,
                                   TestProfile profile,
                                   TestSuite suite) {
        this.testCase = testCase;
        this.profile = profile;
        this.suite = suite;
        this.failedSteps = new LinkedHashMap<TestStep, Exception>();
        this.screenshots = new HashMap<TestStep, String>();
    }

    public void addStep(TestStep step, Exception e, String screenshotPath) {
        failedSteps.put(step, e);
        screenshots.put(step, screenshotPath);
    }

    @Override
    public String getMessage() {
        StringBuilder sb = new StringBuilder("Failed Test: ");
        sb.append(testCase.getId());
        sb.append(" (profile: ");
        sb.append(profile.getId());
        sb.append(", suite: ");
        sb.append(suite.getName());
        sb.append(")\n Failure details [");
        for (Map.Entry<TestStep, Exception> step : failedSteps.entrySet()){
            sb.append("\n    step: ");
            sb.append(step.getKey().getId());
            String message = step.getValue().getMessage();
            if (message != null) {
                sb.append(" (");
                int newlineIndex = message.indexOf('\n');
                if (newlineIndex > 0) {
                    message = message.substring(0, newlineIndex);
                }
                sb.append(message);
                sb.append(")");
            }
            if (screenshots.containsKey(step.getKey())) {
                sb.append(" screenshot: ");
                sb.append(screenshots.get(step.getKey()));
            }
        }
        sb.append("\n]");
        return sb.toString();
    }

    public List<TestStep> getSteps() {
        return newArrayList(failedSteps.keySet());
    }
}
